package org.steven.crm.core.utils;

import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.MultimediaInfo;
import org.apache.tika.Tika;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.regex.Pattern;

/**
 * @Author wuzw
 * @Date 2024/1/4 17:53
 * @Version 1.0
 */
public class FileUtil {
    private static String audioFormat = "^audio/.+";

    private static String videoFormat = "^video/.+";

    public static boolean isAudioFile(String fileFormat) throws Exception {
        return Pattern.matches(audioFormat, fileFormat);
    }

    public static boolean isVideoFile(String fileFormat) throws Exception {
        return Pattern.matches(videoFormat, fileFormat);
    }


    public static FileMeta getFileMeta(File file) throws Exception {
        FileMeta fileMeta = new FileMeta();

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            fileMeta.setSize(getFileSize(fis));
            fileMeta.setHash(getFileHash(fis));
            String fileFormat = getFileFormat(file);
            fileMeta.setMineType(fileFormat);
            if (ImageUtil.isImageFile(fileFormat)) {
                long[] imageWH = ImageUtil.getImageWH(file);
                fileMeta.setWidth(imageWH[0]);
                fileMeta.setHeight(imageWH[1]);
            }
            else if (isAudioFile(fileFormat) || isVideoFile(fileFormat)) {
                Encoder encoder = new Encoder();
                MultimediaInfo m = encoder.getInfo(file);
                long time = new Long(m.getDuration()) / 1000L;
                fileMeta.setDuration(time);
            }
        } finally {
            if (fis != null) {
                fis.close();
            }
        }

        return fileMeta;
    }

    public static String getFileFormat(File file) throws Exception {
        Tika tika = new Tika();
        String mimeType = tika.detect(file);

        return mimeType;
    }

    public static String getFileFormat(FileInputStream fis) throws Exception {
        Tika tika = new Tika();
        String mimeType = tika.detect(fis);

        return mimeType;
    }

    public static long getFileSize(File file) throws Exception {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            return fis.available();
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }

    public static long getFileSize(FileInputStream fis) throws Exception {
        return fis.available();
    }

    public static String getFileHash(File file) throws Exception {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            return getInputStreamHash(fis);
        } finally {
            if (fis != null) {
                fis.close();
            }
        }
    }

    public static String getFileHash(FileInputStream fis) throws Exception {
        return getInputStreamHash(fis);
    }

    private static String getInputStreamHash(InputStream fis) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");

        byte[] buffer = new byte[1024];
        int length = -1;
        while ((length = fis.read(buffer, 0, 1024)) != -1) {
            md.update(buffer, 0, length);
        }

        byte[] md5Bytes  = md.digest();
        BigInteger bigInt = new BigInteger(1, md5Bytes);
        return bigInt.toString(16);
    }

    public static class FileMeta {
        private long size;
        private String hash;
        private String mineType;
        private long width;
        private long height;
        private long duration;

        public long getSize() {
            return size;
        }

        public void setSize(long size) {
            this.size = size;
        }

        public String getHash() {
            return hash;
        }

        public void setHash(String hash) {
            this.hash = hash;
        }

        public String getMineType() {
            return mineType;
        }

        public void setMineType(String mineType) {
            this.mineType = mineType;
        }

        public long getWidth() {
            return width;
        }

        public void setWidth(long width) {
            this.width = width;
        }

        public long getHeight() {
            return height;
        }

        public void setHeight(long height) {
            this.height = height;
        }

        public long getDuration() {
            return duration;
        }

        public void setDuration(long duration) {
            this.duration = duration;
        }
    }

    public static void main(String[] args) throws Exception {
        File file = new File("E:\\download\\chrome\\file_20190827105038867.mp4");

        Encoder encoder = new Encoder();
        MultimediaInfo m = encoder.getInfo(file);
        double time = new Long(m.getDuration()).doubleValue() / 1000;
        System.out.println(time);

    }
}
